Consider the multiplication of the following four matrices.
$$
A \quad\times\quad B \quad\times\quad C \quad\times\quad D \\
(20\times2) \ (2\times30) \ (30\times12) \ (12\times8)
$$
A(B(CD)) (30×12×8) + ( 2×30× 8) + (20× 2× 8) = 3,680 |
There are five different orders in which we can multiply four matrices, each possibly resulting in a different number of elementary multiplications. The third order is the optimal order for multiplying the four matrices. Our goal is to develop an algorithm that determines the optimal order for multiplying n matrices. The optimal order depends only on the dimension of the matrices.
A, B, C, D라는 4개의 행렬에 대해 서로 다른 5가지 방법의 곱셈순서가 있으며, 이 중 세 번째 순서(A((BC)D))가 4개의 행렬을 곱할 때 최적의 순서이다.
연쇄행렬곱셈 알고리즘의 목적은 n개의 행렬을 곱할 때 최적의 순서를 찾는 것이다.
Chained Matrix Multiplication Algorithm
Algorithm Design
We can obtain the following recursive property when multiplying n matrices. For 1 ≤ i ≤ j ≤ n, let
$$
\begin{align}
M[i][j] =& minimum_{(i \le k \le j-1)}(M[i][k] + M[k+1][j] + d_{i-1}d_kd_j), \text{ if } i < j \\
M[i][i] =& 0
\end{align}
$$
M[i][j]는 i< j 일 때 Ai 부터 Aj 까지의 행렬을 곱하는데 필요한 곱셈의 최소횟수를 뜻한다. M[i][i]의 값은 0이다.
Example
Suppose we have the following six matrices :
$$
A_1 \quad\times\quad A_2 \quad\times\quad A_3 \quad\times\quad A_4 \quad\times\quad A_5 \quad \times \quad A_6\\
(5 \ \times \ 2) \quad (2 \ \times \ 3) \quad (3 \ \times \ 4) \quad (4 \ \times \ 6) \quad (6 \ \times \ 7) \quad (7 \ \times \ 8) \\
(d_0 \times d_1) \ \ \ (d_1\times d_2) \ \ \ (d_2\times d_3) \ \ \ (d_3\times d_4) \ \ \ (d_4\times d_5) \ \ \ (d_5\times d_6)
$$
Compute diagonal 1:
M[1][2] = minimum(M[1][k] + M[k+1][2] + d0dkd2) // (1 ≤ k ≤ 1)
= M[1][1] + M[2][2] + d0d1d2
= 0 + 0 + 5 × 2 × 3 = 30.
M[1][2]는 두 개의 행렬을 곱할 때의 연산횟수를 계산한 값이다. M[2][3], M[3][4], M[4][5], M[5][6] 값들 역시 같은 방법으로 계산해준다.
Compute diagonal 2:
M[1][3] = minimum(M[1][k] + M[k+1][3] + d0dkd3) // (1 ≤ k ≤ 2)
= minimum(M[1][1] + M[2][3] + d0d1d3, // ( A1(A2A3) )
M[1][2] + M[3][3] + d0d2d3) // ( (A1A2)A3 )
= minimum(0 + 24 + 5 × 2 × 4,
30 + 0 + 5 × 3 × 4) = 64.
M[1][3]은 A1 부터 A3 까지의 행렬을 곱하는데 필요한 최소횟수이다. 위에서 알 수 있듯이 3개의 행렬을 곱하는 경우의 수는 두 가지(A1(A2A3), (A1A2)A3)이며, 이 중 더 적은 연산을 수행하는 값이 M[1][3]이 된다.
M[1][3]값을 계산하기 위해 앞서 구한 M[1][2], M[2][3] 값들이 이용됨을 알 수 있다. M[2][4], M[3][5], M[4][6] 값들 역시 같은 방법으로 계산해준다.
Compute diagonal 3:
M[1][4] = minimum(M[1][k] + M[k+1][4] + d0dkd4) // (1 ≤ k ≤ 3)
= minimum(M[1][1] + M[2][4] + d0d1d4,
M[1][2] + M[3][4] + d0d2d4,
M[1][3] + M[4][4] + d0d3d4)
= minimum(0 + 72 + 5 × 2 × 6,
30 + 72 + 5 × 3 × 6,
64 + 0 + 5 × 4 × 6) = 132.
M[1][4]는 네 개의 행렬을 곱할 때의 연산횟수를 계산한 값이다. 앞서 구한 M[1][2], M[2][4], …, M[1][3] 등이 계산에 이용됨을 알 수 있다. 값을 재계산하지 않고 찾아서 재사용하는 것이 동적계획법의 특징이다. M[2][5] and M[3][6] 값들 역시 같은 방법으로 계산해주면 된다.
Compute diagonal 4 and 5:
The Optimal Order is.. (A1((((A2A3)A4)A5)A6)) = 348.
diagonal 4와 5 둘다 위의 과정을 반복해주면 된다. 위의 예제의 경우 diagonal 5의 계산이 끝나면 최소한의 연쇄행렬곱셈의 결과값 M[1][6] = 348 을 구할 수 있다. 아래 그림을 참고하면 계산과정을 이해하는데 도움이 된다.
Pseudo Code
int minmult(int n, const int d[ ], index p[ ][ ]) |
Source Code
// File: minmult.h |
// File: minmult.cpp |
// File: minmulttest.cpp |
Time Complexity Analysis
Basic operation
- The instructions executed for each value of k.
Input size
- n, the number of matrices to be multiplied.
Every-Case Time Complexity
- $T(n) = \sum_{diagonal=1}^{n-1}[(n-diagonal) \times diagonal] = \frac{n(n-1)(n+1)}{6} \in \Theta(n^3)$
루프구분 | 루프조건 | 수행 횟수 |
---|---|---|
diagonal-loop 수행 횟수: | 1 to n-1 | n-1 |
i-loop 수행 횟수: | 1 to n-diagonal | n-diagonal |
k-loop 수행 횟수: | i to j-1 | (j-1) - i + 1 = (i + diagonal - 1) - i + 1 = diagonal |
※ j = i + diagonal |
(참고) The bruth-force Time Complexity
2개의 행렬을 곱하는 방법의 수 | AB | t2 = 1 |
3개의 행렬을 곱하는 방법의 수 | (AB)C, A(BC) | t3 = 2 |
4개의 행렬을 곱하는 방법의 수 | ((AB)C)D, (A(BC))D, A((BC)D), A(B(CD)), (AB)(CD) | t4 = 5 |
… | … | … |
n개의 행렬을 곱하는 방법의 수 | exponential-time(Θ(2^n)) | tn >= 2^(n-2) |
무작정 방법으로 연쇄행렬곱셈 최적의 순서를 찾는다면 그 시간복잡도는 exponential-time이다.
Optimization Problem
주어진 문제에 대하여 하나 이상의 많은 해답이 존재할 때, 이 가운데에서 가장 최적인 해답(optimal solution)을 찾아야 하는 문제를 최적화문제(optimization problem)라고 한다. 연쇄행렬곱셈 문제는 최적화문제에 속한다.
Principle of Optimality
n개의 행렬을 곱하는 최적의 순서는 n개의 행렬 중 일부 부분집합에 속하는 행렬을 곱하는 최적의 순서를 항상 포함한다. 예를 들어, 6개의 행렬(A1 , A2 ,…, A6)을 곱할 때의 최적해가 A1 ((((A2 A3) A4) A5) A6)라면, 3개의 행렬(A2, A3, A4)을 곱하는 최적의 순서는 (A2 A3) A4이다. 따라서 최적의 원칙을 만족하게 되며, 동적계획법을 사용하여 문제를 풀 수 있다.
Dynamic Programming Exercises
Find the optimal order, and its cost, for evaluating the product A1 × A2 × A3 × A4 × A5, where
$$
A_1 \ \ \times \ \ A_2 \ \ \times \ \ A_3 \ \ \times \ \ A_4 \ \ \times \ \ A_5 \\
(10 \times 4) (4 \times 5) (5 \times 20) (20 \times 2) (2 \times 50)
$$
Show the final matrices M and P produced by Minimum Multiplications algorithm.
index 1 2 3 4 5 |